package com.wanlian.candy.controller.filter;

import com.wanlian.candy.controller.session.UserSessionInfo;
import com.wanlian.candy.controller.vo.AuthVo;
import com.wanlian.common.ConstantCode;
import com.wanlian.common.UrlConfig;
import com.wanlian.entity.Authority;
import com.wanlian.entity.RoleGroupAuthority;
import com.wanlian.entity.RoleGroupUser;
import com.wanlian.entity.User;
import com.wanlian.json.JsonStringUtil;
import com.wanlian.model.ResultModel;
import com.wanlian.service.*;
import com.wanlian.util.StringUtil;
import com.wanlian.vo.UserAuthorityVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;


public class CommonInterceptor extends HandlerInterceptorAdapter {
    private UrlConfig urlConfig;

    @Autowired
    private UserServices userService;

    @Autowired
    private RoleGroupUserService roleGroupUserService;

    @Autowired
    private AuthorityServices authorityService;

    @Autowired
    private RoleGroupAuthorityService roleGroupAuthorityService;

    private String getServerUrl(HttpServletRequest request) {
        String url = null;
        url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/";
        return url;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
        String requestUri = request.getRequestURI();
        String contextPath = request.getContextPath();
        String url = requestUri.substring(contextPath.length());
        System.out.println("url:" + url);
        if (isNotCheckUrl(url)) {
            return true;
        } else {
            if (checkHeaderAuth(request, response)) {
                UserSessionInfo userinfo = (UserSessionInfo) request.getSession().getAttribute(ConstantCode.USERINFO_KEY);
                String auth = request.getHeader("Authorization");
              //  System.out.println("Authorization is:" + auth);
                if (StringUtil.hasValue(auth)) {
                    AuthVo authVo = JsonStringUtil.readValue(auth, AuthVo.class);
                    if (authVo.getPlatForm().equals(ConstantCode.PLATFORM_APP)) {
                        User user = userService.queryUserByPhone(authVo.getAuth());
                        if (user != null) {
                            System.out.println("***********APP端用户重新获取，电话：" + auth);
                            userinfo.setLoginUser(user);
                            return true;
                        } else {
                            ResultModel resultModel = new ResultModel();
                            resultModel.setBresult(false);
                            resultModel.setMessage("用户不存在或者已经被删除");
                            String msg = JsonStringUtil.writeValueAsString(resultModel);
                            response.setCharacterEncoding("UTF-8");
                            // OutputStream os = response.getOutputStream();
                            PrintWriter os = response.getWriter();
                            os.write(msg);
                            // os.write(new String(msg).getBytes());
                            os.flush();
                            // os.close();
                            return true;
                        }
                    }
                }
                if (!checkHasAuth(url, userinfo)) {
                    System.out.println(url+"~~~false");
                    String HttpMethod = request.getMethod();
                    if (request.getMethod().toUpperCase().equals("POST")) {
                        System.out.println(HttpMethod);
                    }
                        ResultModel resultModel = new ResultModel();
                        resultModel.setBresult(false);
                        resultModel.setErrorTag(1);
                        resultModel.setMessage("暂无权限");
                        String msg = JsonStringUtil.writeValueAsString(resultModel);
                        response.setCharacterEncoding("UTF-8");
                        PrintWriter os = response.getWriter();
                        os.write(msg);
                        os.flush();
                        //os.close();
                    return false;
                } else {
                    System.out.println(url+"~~~true");
                    return true;
                }
            } else {
                if (request.getMethod().toUpperCase().equals("POST")) {
                    ResultModel resultModel = new ResultModel();
                    resultModel.setBresult(false);
                    resultModel.setErrorTag(1);
                    resultModel.setMessage("登录失效，请重新登录");
                    String msg = JsonStringUtil.writeValueAsString(resultModel);
                    response.setCharacterEncoding("UTF-8");
                    PrintWriter os = response.getWriter();
                    os.write(msg);
                    os.flush();
                    return false;
                } else if (request.getMethod().toUpperCase().equals("GET")) {
                    System.out.println("跳转到登录");
                    String rooturl = getServerUrl(request);
                    System.out.println(rooturl);
                    response.sendRedirect(rooturl);
                    return false;
                }
            }
        }
        return true;
    }

    private boolean checkHeaderAuth(HttpServletRequest request, HttpServletResponse response) {
        // 永远为空
        String auth = request.getHeader("Authorization");
       // System.out.println("Authorization is:" + auth);
        if (auth != null) {
            System.out.println("phone authorization:" + request.getSession().getId());
        }
        UserSessionInfo userinfo = (UserSessionInfo) request.getSession().getAttribute(ConstantCode.USERINFO_KEY);
        if (userinfo == null) {
            userinfo = new UserSessionInfo();
        }
        if (userinfo.getLoginUser() != null) {
            request.getSession().setMaxInactiveInterval(24 * 60 * 60);
            return true;
        } else {
            if (StringUtil.hasValue(auth)) {
                AuthVo authVo = JsonStringUtil.readValue(auth, AuthVo.class);
                User user = userService.queryUserByPhone(authVo.getAuth());
                if (user != null) {
                    System.out.println("***********session重新生成，电话：" + auth);
                    userinfo.setLoginUser(user);
                    request.getSession().setAttribute("UserSessionInfo", userinfo);
                    return true;
                } else {
                    return false;
                }
            }
        }
        return false;
    }

    private boolean isNotCheckUrl(String url) {
        if (url.equals("/")) {
            return true;
        }
        List<String> ignoreUrlList = urlConfig.getIgnoreUrlList();
        for (String ext : ignoreUrlList) {
            if (url.toUpperCase().endsWith(ext.toUpperCase())) {
                return true;
            }
        }
        return false;
    }

    private boolean checkHasAuth(String url, UserSessionInfo userinfo) {
        // 判断url是否受权限控制
        System.out.println("checkHasAuth:"+url);
        int userId=userinfo.getLoginUser().getId();
        User user=userService.queryById(userId);
        if(!user.getManagement()){
            return true;
        }
        Authority authority=authorityService.queryByMethodUrl(url);
        RoleGroupUser roleGroupUser=roleGroupUserService.queryByUid(userId);
        if(authority==null){
            //权限无配置，默认返回true
            return true;
        }
        if(roleGroupUser==null){
            return false;
        }else{
           RoleGroupAuthority roleGroupAuthority= roleGroupAuthorityService.queryByGAid(roleGroupUser.getGroupid(),authority.getAuthorityId());
            if(roleGroupAuthority==null){
                return false;
            }else{
                return true;
            }
        }
    }



    public UrlConfig getUrlConfig() {
        return urlConfig;
    }

    public void setUrlConfig(UrlConfig urlConfig) {
        this.urlConfig = urlConfig;
    }
}
